package com.info.zhiduoduo.admin.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.fastjson.JSONObject;
import com.info.zhiduoduo.admin.model.formbean.crowdsource.UploadCrowdsourceFormBean;
import com.info.zhiduoduo.common.constants.Constants;
import com.info.zhiduoduo.common.constants.SmartResult;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.constants.crowdsource.CrowdsourceRegfromType;
import com.info.zhiduoduo.common.exception.SmartException;
import com.info.zhiduoduo.common.utils.IdentityUtil;
import com.info.zhiduoduo.common.utils.RandomUtil;
import com.info.zhiduoduo.core.formbean.BankCardElementFormBean;
import com.info.zhiduoduo.core.listener.BaseAnalysisEventListener;
import com.info.zhiduoduo.core.service.impl.BankCardElementCertificationService;
import com.info.zhiduoduo.repository.dto.company.CompanyDetailDto;
import com.info.zhiduoduo.repository.entity.crowdsource.Crowdsource;
import com.info.zhiduoduo.repository.entity.crowdsource.CrowdsourceAccount;
import com.info.zhiduoduo.repository.mapper.crowdsource.CrowdsourceAccountMapper;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;


@Getter
@Slf4j
public class UploadCrowdsourceListener extends BaseAnalysisEventListener<UploadCrowdsourceFormBean> {

    //解析后的数据集合
    List<UploadCrowdsourceFormBean> list = new ArrayList<>();
    //新增自然人ID集合
    Set<Integer> insertIds = new HashSet<>();

    CompanyDetailDto companyDetailDto;

    CrowdsourceAccountMapper crowdsourceAccountMapper;

    public UploadCrowdsourceListener(CompanyDetailDto companyDetailDto, CrowdsourceAccountMapper crowdsourceAccountMapper) {
        this.companyDetailDto = companyDetailDto;
        this.crowdsourceAccountMapper = crowdsourceAccountMapper;
    }

    @Override
    public void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context) {
        int index = context.readRowHolder().getRowIndex() + 1;
        // 校验模板列
        if (index == 2) {
            int sexColumn = 1;//性别列(从左到右，下标0开始)
            if(headMap == null || headMap.get(sexColumn) == null
                    || !StringUtils.contains(headMap.get(sexColumn).getStringValue(),"性别")){
                throw new SmartException(StatusMsg.StatusMsg_339);
            }
        }
    }
    @Override
    public void invoke(UploadCrowdsourceFormBean formBean, AnalysisContext analysisContext) {

        super.invoke(formBean, analysisContext);

        // 单条数据校验
        boolean result = checkValidExcelData(formBean, index);
        if (result) {
            list.add(formBean);
        }
    }

    /**
     * 数据校验
     *
     * @param formBean
     * @param index
     * @return
     */
    private boolean checkValidExcelData(UploadCrowdsourceFormBean formBean, int index) {
        String identityType = formBean.getIdentityType();
        if ("男".equals(formBean.getSex())) {
            formBean.setSexS(1);
        } else {
            formBean.setSexS(2);
        }
        //限制不能是港澳通行证
        if ("港澳台胞证".equals(identityType)) {
            errorPrompt.add("请检查第[" + index + "]行数据：证件类型必须是身份证");
            return false;
        }
        formBean.setIdentityTypeS(1);
        // 校验身份证长度
        if(!IdentityUtil.isLegalIdCard(formBean.getIdno())){
            errorPrompt.add("请检查第[" + index + "]行数据：身份证号格式错误");
            return false;
        }

        // 校验年龄 限制年龄为18-65
        int age = IdentityUtil.countAge(formBean.getIdno());
        if(age < 18 || age > 65){
            errorPrompt.add("请检查第[" + index + "]行数据：自然人必须是18-65周岁");
            return false;
        }

        // 姓名+身份证号+卡号 已经存在数据库的话，就不再调下面的两个接口（核验三要素+银行卡校验）
        CrowdsourceAccount account = crowdsourceAccountMapper.findByIdno(formBean.getIdno(), formBean.getRealname());
        if(account != null && StringUtils.equals(account.getAcctno(),formBean.getAcctno())){
            return true;
        }

        //1核验一致; 2核验不一致; 3无效卡号或卡状态异常，请换卡重试或联系发卡行;
        Integer bankResult = BankCardElementCertificationService.getBankCardElement(BankCardElementFormBean.ofThree(formBean.getRealname(), formBean.getAcctno(), formBean.getIdno()));
        if (bankResult == null) {
            errorPrompt.add("请检查第[" + index + "]行数据：银行卡核验出错");
            return false;
        } else if (bankResult == 2) {
            errorPrompt.add("请检查第[" + index + "]行数据：姓名+身份证+银行卡号三要素核验不一致");
            return false;
        } else if (bankResult == 3) {
            errorPrompt.add("请检查第[" + index + "]行数据：无效卡号或卡状态异常，请换卡重试或联系发卡行");
            return false;
        }
        // 银行卡校验增加校验是否是信用卡款，提示语：银行卡必须为借记卡
        try {
            JSONObject jsonObject = BankCardElementCertificationService.homeQuery(formBean.getAcctno());
            String type = jsonObject.getString("type");
            if (!"借记卡".equals(type)) {
                errorPrompt.add("请检查第[" + index + "]行数据：银行卡必须为借记卡");
                return false;
            }
        } catch (Exception e) {
            log.error("银行卡:{}归属地查询失败：{}", formBean.getAcctno(), e);
            errorPrompt.add("请检查第[" + index + "]行数据：网络波动，请稍后再试");
            return false;
        }

        return true;
    }


    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 有失败的数据，则返回
        if (CollectionUtils.isNotEmpty(errorPrompt)) {
            smartResult = SmartResult.fail(StatusMsg.StatusMsg_1109, errorPrompt);
            return;
        }
        if (CollectionUtils.isEmpty(list)){
            smartResult = SmartResult.ofEmptyData();
            return;
        }
        for (UploadCrowdsourceFormBean bean:list){
            // 判断身份证号是否存在,存在则更新银行卡等数据
            CrowdsourceAccount account = crowdsourceAccountMapper.findByIdno(bean.getIdno(), null);
            if (account != null) {
                account.setAcctno(bean.getAcctno())
                       .setRealname(bean.getRealname())
                       .setAcctphone(bean.getPhone())
                       .setBankname(bean.getBankname())
                       .setAlipayLogonId(bean.getAlipayLogonId())
                       .setRealnameAuth(Constants.crowdsource_auth_3)
                       .updateById();
                continue;
            }
            // 新增自然人数据
            Crowdsource crowdsource = new Crowdsource()
                    .setPhone(bean.getPhone())
                    .setRegfrom(CrowdsourceRegfromType.COMPANY_ADD)
                    .setNickname(bean.getRealname())
                    .setSex(bean.getSexS())
                    .setState(Constants.crowdsource_state_2);
            if (!crowdsource.insert()) continue;

            CrowdsourceAccount crowdsourceAccount = new CrowdsourceAccount()
                    .setCrowdsourceid(crowdsource.getCrowdsourceid())
                    .setBindcompid(companyDetailDto.getCompid())
                    .setRealnameAuth(Constants.crowdsource_auth_3)
                    .setRealname(bean.getRealname())
                    .setAcctno(bean.getAcctno())
                    .setIdno(bean.getIdno())
                    .setAcctphone(bean.getPhone())
                    .setBankname(bean.getBankname())
                    .setIdentityType(bean.getIdentityTypeS())
                    .setContractNo(genContractNo())
                    .setAlipayLogonId(bean.getAlipayLogonId());
            if (!crowdsourceAccount.insert()) continue;

            insertIds.add(crowdsource.getCrowdsourceid());
        }

        smartResult = SmartResult.success();
    }

    private String genContractNo() {
        return RandomUtil.createRandomNo("CROWD_", "");
    }
}
